#!/bin/bash

# MD2PPT 自动部署脚本
# 使用方法: ./scripts/deploy.sh [环境类型]
# 环境类型: dev, staging, production

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查依赖
check_dependencies() {
    log_info "检查依赖..."
    
    if ! command -v docker &> /dev/null; then
        log_error "Docker 未安装，请先安装 Docker"
        exit 1
    fi
    
    if ! command -v docker-compose &> /dev/null; then
        log_error "Docker Compose 未安装，请先安装 Docker Compose"
        exit 1
    fi
    
    log_success "依赖检查完成"
}

# 环境配置
setup_environment() {
    local env_type=$1
    log_info "设置 $env_type 环境..."
    
    if [ ! -f ".env" ]; then
        if [ -f ".env.example" ]; then
            cp .env.example .env
            log_info "已创建 .env 文件，请根据需要修改配置"
        else
            log_error ".env.example 文件不存在"
            exit 1
        fi
    fi
    
    # 根据环境类型设置不同的配置
    case $env_type in
        "dev")
            sed -i.bak 's/API_HOST=.*/API_HOST=127.0.0.1/' .env
            sed -i.bak 's/FILE_TTL=.*/FILE_TTL=7200/' .env
            ;;
        "staging")
            sed -i.bak 's/API_HOST=.*/API_HOST=0.0.0.0/' .env
            sed -i.bak 's/FILE_TTL=.*/FILE_TTL=3600/' .env
            ;;
        "production")
            sed -i.bak 's/API_HOST=.*/API_HOST=0.0.0.0/' .env
            sed -i.bak 's/FILE_TTL=.*/FILE_TTL=1800/' .env
            sed -i.bak 's/CORS_ORIGINS=.*/CORS_ORIGINS=["https:\/\/yourdomain.com"]/' .env
            ;;
    esac
    
    log_success "环境配置完成"
}

# 构建镜像
build_images() {
    log_info "构建 Docker 镜像..."
    
    docker-compose -f config/docker/docker-compose.yml build --no-cache
    
    log_success "镜像构建完成"
}

# 启动服务
start_services() {
    local env_type=$1
    log_info "启动服务..."
    
    # 创建必要的目录
    mkdir -p storage logs
    
    # 启动服务
    docker-compose -f config/docker/docker-compose.yml up -d
    
    # 等待服务启动
    log_info "等待服务启动..."
    sleep 10
    
    # 健康检查
    if health_check; then
        log_success "服务启动成功"
        show_service_info
    else
        log_error "服务启动失败"
        docker-compose -f config/docker/docker-compose.yml logs
        exit 1
    fi
}

# 健康检查
health_check() {
    local max_attempts=30
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if curl -s -f http://localhost:8000/health > /dev/null 2>&1; then
            return 0
        fi
        
        log_info "健康检查尝试 $attempt/$max_attempts..."
        sleep 2
        ((attempt++))
    done
    
    return 1
}

# 显示服务信息
show_service_info() {
    echo ""
    log_success "=== MD2PPT 服务部署完成 ==="
    echo ""
    echo -e "${BLUE}API 服务:${NC} http://localhost:8000"
    echo -e "${BLUE}API 文档:${NC} http://localhost:8000/docs"
    echo -e "${BLUE}健康检查:${NC} http://localhost:8000/health"
    echo -e "${BLUE}MCP 服务:${NC} localhost:8001"
    echo ""
    echo -e "${BLUE}常用命令:${NC}"
    echo "  查看日志: docker-compose -f config/docker/docker-compose.yml logs -f"
    echo "  停止服务: docker-compose -f config/docker/docker-compose.yml down"
    echo "  重启服务: docker-compose -f config/docker/docker-compose.yml restart"
    echo "  查看状态: docker-compose -f config/docker/docker-compose.yml ps"
    echo ""
}

# 测试部署
test_deployment() {
    log_info "测试部署..."
    
    # 测试健康检查
    if ! curl -s -f http://localhost:8000/health > /dev/null; then
        log_error "健康检查失败"
        return 1
    fi
    
    # 测试基本转换
    local test_result=$(curl -s -X POST http://localhost:8000/api/v1/convert \
        -H "Content-Type: application/json" \
        -d '{"markdown_content":"# Test\n\n## Hello\n- World","options":{"theme":"default"}}' \
        | grep -o '"success":[[:space:]]*true')
    
    if [[ "$test_result" =~ \"success\":[[:space:]]*true ]]; then
        log_success "转换测试通过"
    else
        log_error "转换测试失败"
        return 1
    fi
    
    # 测试主题接口
    if curl -s -f http://localhost:8000/api/v1/themes > /dev/null; then
        log_success "主题接口测试通过"
    else
        log_error "主题接口测试失败"
        return 1
    fi
    
    log_success "所有测试通过"
}

# 清理函数
cleanup() {
    log_info "清理临时文件..."
    rm -f .env.bak
}

# 更新服务
update_services() {
    log_info "更新服务..."
    
    # 拉取最新代码
    git pull origin main
    
    # 重新构建并启动
    docker-compose -f config/docker/docker-compose.yml down
    docker-compose -f config/docker/docker-compose.yml build --no-cache
    docker-compose -f config/docker/docker-compose.yml up -d
    
    # 健康检查
    if health_check; then
        log_success "服务更新完成"
    else
        log_error "服务更新失败"
        exit 1
    fi
}

# 备份数据
backup_data() {
    local backup_dir="backups/$(date +%Y%m%d_%H%M%S)"
    log_info "备份数据到 $backup_dir..."
    
    mkdir -p "$backup_dir"
    
    # 备份配置
    cp .env "$backup_dir/"
    
    # 备份存储数据
    if [ -d "storage" ]; then
        tar -czf "$backup_dir/storage.tar.gz" storage/
    fi
    
    # 备份日志
    if [ -d "logs" ]; then
        tar -czf "$backup_dir/logs.tar.gz" logs/
    fi
    
    log_success "数据备份完成: $backup_dir"
}

# 恢复数据
restore_data() {
    local backup_dir=$1
    
    if [ -z "$backup_dir" ]; then
        log_error "请指定备份目录"
        exit 1
    fi
    
    if [ ! -d "$backup_dir" ]; then
        log_error "备份目录不存在: $backup_dir"
        exit 1
    fi
    
    log_info "从 $backup_dir 恢复数据..."
    
    # 停止服务
    docker-compose -f config/docker/docker-compose.yml down
    
    # 恢复配置
    if [ -f "$backup_dir/.env" ]; then
        cp "$backup_dir/.env" .
    fi
    
    # 恢复存储数据
    if [ -f "$backup_dir/storage.tar.gz" ]; then
        tar -xzf "$backup_dir/storage.tar.gz"
    fi
    
    # 恢复日志
    if [ -f "$backup_dir/logs.tar.gz" ]; then
        tar -xzf "$backup_dir/logs.tar.gz"
    fi
    
    # 重启服务
    docker-compose -f config/docker/docker-compose.yml up -d
    
    log_success "数据恢复完成"
}

# 监控服务
monitor_services() {
    log_info "监控服务状态..."
    
    while true; do
        echo "=== $(date) ==="
        
        # 检查容器状态
        docker-compose -f config/docker/docker-compose.yml ps
        
        # 检查健康状态
        if curl -s -f http://localhost:8000/health > /dev/null; then
            echo -e "${GREEN}✓ API 服务健康${NC}"
        else
            echo -e "${RED}✗ API 服务异常${NC}"
        fi
        
        # 检查资源使用
        echo "容器资源使用:"
        docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
        
        echo ""
        sleep 30
    done
}

# 主函数
main() {
    local env_type=${1:-"dev"}
    local action=${2:-"deploy"}
    
    echo -e "${BLUE}"
    echo "================================"
    echo "    MD2PPT 部署脚本"
    echo "    环境: $env_type"
    echo "    操作: $action"
    echo "================================"
    echo -e "${NC}"
    
    case $action in
        "deploy")
            check_dependencies
            setup_environment "$env_type"
            build_images
            start_services "$env_type"
            test_deployment
            cleanup
            ;;
        "update")
            update_services
            ;;
        "backup")
            backup_data
            ;;
        "restore")
            restore_data "$3"
            ;;
        "monitor")
            monitor_services
            ;;
        "test")
            test_deployment
            ;;
        "health")
            if health_check; then
                log_success "服务健康"
                exit 0
            else
                log_error "服务异常"
                exit 1
            fi
            ;;
        *)
            echo "使用方法: $0 [环境] [操作]"
            echo ""
            echo "环境类型:"
            echo "  dev        - 开发环境"
            echo "  staging    - 测试环境" 
            echo "  production - 生产环境"
            echo ""
            echo "操作类型:"
            echo "  deploy     - 部署服务（默认）"
            echo "  update     - 更新服务"
            echo "  backup     - 备份数据"
            echo "  restore    - 恢复数据"
            echo "  monitor    - 监控服务"
            echo "  test       - 测试服务"
            echo "  health     - 健康检查"
            echo ""
            echo "示例:"
            echo "  $0 production deploy"
            echo "  $0 dev update"
            echo "  $0 production backup"
            echo "  $0 production restore backups/20241225_120000"
            exit 1
            ;;
    esac
}

# 捕获中断信号
trap cleanup EXIT

# 执行主函数
main "$@"